package com.boe.csb.core.common.pool;

import com.boe.csb.core.common.utils.PropertyUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class FtpClientPool implements ObjectPool<FTPClient> {
	
	private static final Logger logger = LoggerFactory.getLogger(FtpClientPool.class);
	
	private static final int DEFAULT_POOL_SIZE = 10;
	
	private static BlockingQueue<FTPClient> pool;
	
	private final FtpClientFactory factory;
	
	private static String workHomeDic = "";
	
	public FtpClientPool(){
		this.factory = new FtpClientFactory();
		pool = new ArrayBlockingQueue<FTPClient>(DEFAULT_POOL_SIZE * 2);
		init();
	}
	
	private void init(){
		workHomeDic = PropertyUtils.getProperty("ftp.workDic");
		try {
			FTPClient client =  factory.makeObject();
			workHomeDic = client.printWorkingDirectory();//转换为绝对路径
		} catch (Exception e) {
			logger.error("init ftpClient pool fail err:", e);
		}
	}

	@Override
	public void addObject() throws Exception, IllegalStateException,
			UnsupportedOperationException {
		pool.offer(factory.makeObject(), 3, TimeUnit.SECONDS);
	}

	@Override
	public FTPClient borrowObject() throws Exception, NoSuchElementException,
			IllegalStateException {
		FTPClient client = pool.poll();
		if(client == null){
			client = factory.makeObject();
			addObject();//FIXME
		}else if(!factory.validateObject(client)){
			invalidateObject(client);//使对象在池中失效
			client = factory.makeObject();//创建新的对象
			addObject();//FIXME
		}
		
		return client;
	}

	@Override
	public void clear() throws Exception, UnsupportedOperationException {
		
	}

	@Override
	public void close() throws Exception {
		Iterator<FTPClient> it = pool.iterator();
		while(it.hasNext()){
			FTPClient client = pool.take();
			factory.destroyObject(client);
		}
	}

	@Override
	public int getNumActive() throws UnsupportedOperationException {
		return 0;
	}

	@Override
	public int getNumIdle() throws UnsupportedOperationException {
		return 0;
	}

	@Override
	public void invalidateObject(FTPClient client) throws Exception {
		pool.remove(client);
	}

	@Override
	public void returnObject(FTPClient client) throws Exception {
		
		if(client != null){
			if(!client.changeWorkingDirectory(workHomeDic)){
				factory.destroyObject(client);
				return;
			}
		}
		
		if((client != null) && !pool.offer(client, 3, TimeUnit.SECONDS)){
			try{
				factory.destroyObject(client);
			}catch(IOException e){
				logger.error("", e);
			}
		}
	}

	@Override
	public void setFactory(PoolableObjectFactory<FTPClient> arg0)
			throws IllegalStateException, UnsupportedOperationException {
		
	}}
